---
id: unit2
title: loader
---

import { Image } from "antd";

import postcss from "./img/postcss.png";

loader 是处理文件的规则。  
webpack 是基于 Node 的，所以默认是可以处理 js 文件的，所以无需额外配置，但是在代码里使用 js 之外的文件(css, jpg……)，webpack 在构建时就懵逼了，不知道怎么办。这个时候就需要 loader 来告诉 webpack，怎么处理这些文件。

## 演示： 不配置 loader 情况

1. 首先在 src 下面新建一个 css 文件夹，放入一个 index.css 文件，内容如下：

```css
/** index.css **/
body {
  width: 500px;
  height: 500px;
  background-color: pink;
}
```

2. 在 index.js 的头部加入以下代码

```js
import "./index.css";
```

3. `npm run build`

:::warning 报错信息
ERROR in ./src/css/index.css 1:5
Module parse failed: Unexpected token (1:5)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

> body {
> | width: 500px;
> | height: 500px;
> @ ./src/index.js 1:0-25

:::

提示我们 模块加载失败，要我们去配置 css 的相关规则，那我们就去配置吧。

## css loader 配置

### 开始配置

我们在这里一步到位配置完

1. 安装需要的 loader ` npm i css-loader@4 style-loader@2 postcss-loader@4 -D`
2. 下载 postcss 配置包 `npm i autoprefixer@9 -D`

3. webpack.config.js 加入处理 css 的配置:

```js
const path = require("path");
const autoprefixer = require("autoprefixer");
module.exports = {
  mode: "development", // 模式（分为开发模式，和生产模式）
  entry: {
    // 入口文件配置
    main: "./src/index.js",
  },
  module: {
    rules: [
      {
        test: /\.(css|scss)$/,
        use: [
          "style-loader",
          "css-loader",
          // 'sass-loader',
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  autoprefixer({
                    overrideBrowserslist: [
                      "last 10 Chrome versions",
                      "last 5 Firefox versions",
                      "Safari >= 6",
                      "ie> 8",
                    ],
                  }),
                ],
              },
            },
          },
        ],
      },
    ],
  },
  output: {
    // 输出文件配置
    filename: "main.js",
    path: path.resolve(__dirname, "dist"),
  },
};
```

4. 执行 `npm run build`

:::tip
loader 执行的顺序是从后向前的，在这里依次是 postcss-loader、css-loader、style-loader
:::

### 配置解释

1. postcss-loader 负责给一些特殊 css 属性加私有前缀，来保证各个浏览器都支持你写的样式。

<Image width={200} src={postcss} />

2. css-loader 负责解析各种方式引入的 css (url()、 import、require()) 并转换成浏览器认识的 css。

```js
options:{ importLoaders: 2, modules:true }
```

3. style-loader 负责把 css-loader 翻译过来的内容插入相应的位置。

## 图片、音频、视频…… loader 配置

上面的 css 这种需先翻译成浏览器认识的 css 文件，但是像图片，音频，视频这种不需要翻译转换的，只需要使用 file-loader 来保证位置引入正确即可。

### 开始配置

1. 先下载 file-loader ` npm i file-loader -D`
2. webpack.config.js 里的 module.rules 添加处理图片的 loader。内容如下：

```js

{
    test: /\.(jpg|jpeg|png|gif)$/,
    use: {
        loader: 'file-loader',
        options:  {
            outputPath: './dist/'
        }
    }
}
```

3. 向 index.js 里插入图片内容：

```js
import imgSrc from "./img/a.png";
console.log("imgSrc", imgSrc);
let img = new Image();
img.src = "./dist/" + imgSrc; // 当前html文件在根目录，打包的文件在dist目录，先在此处添加dist文件夹
document.querySelector("body").append(img);
```

4. `npm run build` 完成。

5. 扩展内容： 这时 dist 里的图片名称已经默认给改了，如果不想让它更改，options 可以 webpack 提供的占位符。

```js
options: {
  name: "[name].[ext]";
}
```

### 优化图片

图片我们可以使用 url-loader 来进行优化。  
它和 file-loader 基本类似，不同点是它可以把图片转化成 base64，以 url 的形式引入，适合一些小的图片，这样就能减少 http 请求。

1. `npm i url-loader@2 -D`
2. webpack.config.js 图片配置更换成 url-loader 的配置，内容如下：

```js
{
    test: /\.(jpg|jpeg|png|gif)$/,
    use: {
        loader: 'url-loader',
        options: {
            name: '[name]_[hash].[ext]',
            outputPath: 'img/',
            limit: 10240 // 小于等于10k的将转换成base64
        }
    }
}
```

## 字体 loader 配置

我们最常用的恐怕就是 iconfont 里的字体图标了，这种不需要编译的都是一样的。

1. webpack.config.js 添加字体文件对应的 loader，正常使用即可。不再演示。

```js
{
    test: /\.(eot|ttf|svg|woff|woff2)$/,
    use: {
        loader: 'file-loader'
    }
}
```

## TS loader 配置

`npm i ts-loader@8 typescript -D`

loader 配置

```js
module: {
        rules: [
          {
            test: /\.(ts)$/,
            use: "ts-loader",
            exclude: /node_modules/
          },
        ],
      },
```

## vue loader 配置

`npm i vue-loader -D`

```js
const { VueLoaderPlugin } = require("vue-loader");
plugins: [
  // ……
  new VueLoaderPlugin(),
];
```

- demo 
```js 
// index.js

import { createApp } from 'vue'
import App from './index.vue'

const app = createApp(App)

app.mount('#app')
```

```js 
// index.vue
<template>
    <div>111</div>
</template>

<script>
export default {
    setup() {
        alert(1)
    },
}
</script>
```
